// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

#ifndef OBSERVABLE_H_
#define OBSERVABLE_H_

#include <stddef.h>
#include "status/rot_status.h"
#include "platform.h"


/**
 * A single observer in the observers list.
 */
struct observable_observer {
	void *observer;						/**< The registered observer. */
	struct observable_observer *next;	/**< The next entry in the list. */
};


/**
 * Manager for observer registration and notification.
 */
struct observable {
	platform_mutex lock;						/**< Synchronization for the observer list. */
	struct observable_observer *observer_head;	/**< Head of the observers list. */
};


int observable_init (struct observable *observable);
void observable_release (struct observable *observable);

int observable_add_observer (struct observable *observable, void *observer);
int observable_remove_observer (struct observable *observable, void *observer);

int observable_notify_observers (struct observable *observable, size_t callback_offset);
int observable_notify_observers_with_ptr (struct observable *observable, size_t callback_offset,
	void *arg);


#define	OBSERVABLE_ERROR(code)		ROT_ERROR (ROT_MODULE_OBSERVABLE, code)

/**
 * Error codes that can be generated by an observer manager.
 */
enum {
	OBSERVABLE_INVALID_ARGUMENT = OBSERVABLE_ERROR (0x00),	/**< Input parameter is null or not valid. */
	OBSERVABLE_NO_MEMORY = OBSERVABLE_ERROR (0x01),			/**< Memory allocation failed. */
};


#endif /* OBSERVABLE_H_ */
